function rand(min, max) {
    return min + Math.round(Math.random() * (max - min));
}
/**
 * 打字机特效
 */
export default class Typing {
    config = {
        minTime: 100,
        maxTime: 300,
        callback: undefined,
        targetString: "",
        cursorString: "|",
        cursorInterval: 500,
        render: (outString) => {
            console.clear();
            console.log(outString);
        },
    };
    currentString = "";
    currentIndex = 0;
    hasCursor = true;
    cursorTimer = 0;
    constructor(options) {
        if (options)
            this.updateConfig(options);
    }
    run(options) {
        if (typeof options === "string") {
            this.config.targetString = options;
        }
        if (typeof options === "object") {
            this.updateConfig(options);
        }
        this.currentIndex = 0;
        this.currentString = "";
        return new Promise((resolve) => {
            const next = async () => {
                this.config.targetString += "";
                this.stopCursor(); // 停止光标
                this.runCursor(); // 开启光标（竞争）
                if (this.currentIndex < this.config.targetString.length) {
                    this.currentString += this.config.targetString[this.currentIndex];
                    this.currentIndex++;
                }
                else {
                    this.currentString = this.config.targetString;
                }
                await this.render();
                if (this.currentIndex < this.config.targetString.length) {
                    setTimeout(next.bind(this), // 递归自身，并传参
                    rand(this.config.minTime, this.config.maxTime));
                }
                else {
                    if (resolve)
                        resolve(true); // 所有字符自增完成
                    if (this.config.callback)
                        this.config.callback();
                }
            };
            next();
        });
    }
    updateConfig(options) {
        if (options)
            this.config = { ...this.config, ...options };
    }
    render() {
        return this.config.render?.(this.outString);
    }
    get outString() {
        return (this.currentString + (this.hasCursor ? this.config.cursorString : ""));
    }
    runCursor() {
        this.cursorTimer = setInterval(this.toggleCursor.bind(this), this.config.cursorInterval);
    }
    stopCursor() {
        clearInterval(this.cursorTimer);
        this.hasCursor = true;
    }
    toggleCursor() {
        this.hasCursor = !this.hasCursor;
        this.render();
    }
}
